import type {MenuRecordRaw} from '@/typings/core';

import {computed, onBeforeMount, ref, watch} from 'vue';
import {useRoute} from 'vue-router';

import {preferences, usePreferences} from '@/preferences/effects';
import {useAccessStore} from '@/stores/effects';
import {findRootMenuByPath} from '@/utils/tool';

import {useNavigation} from './use-navigation';

function useMixedMenu() {
    const {navigation} = useNavigation();
    const accessStore = useAccessStore();
    const route = useRoute();
    const splitSideMenus = ref<MenuRecordRaw[]>([]);
    const rootMenuPath = ref<string>('');
    /** 记录当前顶级菜单下哪个子菜单最后激活 */
    const defaultSubMap = new Map<string, string>();
    const {isMixedNav} = usePreferences();

    const needSplit = computed(
        () => preferences.navigation.split && isMixedNav.value,
    );

    const sidebarVisible = computed(() => {
        const enableSidebar = preferences.sidebar.enable;
        if (needSplit.value) {
            return enableSidebar && splitSideMenus.value.length > 0;
        }
        return enableSidebar;
    });
    const menus = computed(() => accessStore.accessMenus);

    /**
     * 头部菜单
     */
    const headerMenus = computed(() => {
        if (!needSplit.value) {
            return menus.value;
        }
        return menus.value.map((item) => {
            return {
                ...item,
                children: [],
            };
        });
    });

    /**
     * 侧边菜单
     */
    const sidebarMenus = computed(() => {
        return needSplit.value ? splitSideMenus.value : menus.value;
    });

    /**
     * 侧边菜单激活路径
     */
    const sidebarActive = computed(() => {
        return (route?.meta?.activePath as string) ?? route.path;
    });

    /**
     * 头部菜单激活路径
     */
    const headerActive = computed(() => {
        if (!needSplit.value) {
            return route.path;
        }
        return rootMenuPath.value;
    });

    /**
     * 菜单点击事件处理
     * @param key 菜单路径
     * @param mode 菜单模式
     */
    const handleMenuSelect = (key: string, mode?: string) => {
        if (!needSplit.value || mode === 'vertical') {
            navigation(key);
            return;
        }

        const rootMenu = menus.value.find((item) => item.path === key);
        rootMenuPath.value = rootMenu?.path ?? '';
        splitSideMenus.value = rootMenu?.children ?? [];
        if (splitSideMenus.value.length === 0) {
            navigation(key);
        } else if (rootMenu && preferences.sidebar.autoActivateChild) {
            navigation(
                defaultSubMap.has(rootMenu.path)
                    ? (defaultSubMap.get(rootMenu.path) as string)
                    : rootMenu.path,
            );
        }
    };

    /**
     * 侧边菜单展开事件
     * @param key 路由路径
     * @param parentsPath 父级路径
     */
    const handleMenuOpen = (key: string, parentsPath: string[]) => {
        if (parentsPath.length <= 1 && preferences.sidebar.autoActivateChild) {
            navigation(
                defaultSubMap.has(key) ? (defaultSubMap.get(key) as string) : key,
            );
        }
    };

    /**
     * 计算侧边菜单
     * @param path 路由路径
     */
    function calcSideMenus(path: string = route.path) {
        let {rootMenu} = findRootMenuByPath(menus.value, path);
        if (!rootMenu) {
            rootMenu = menus.value.find((item) => item.path === path);
        }
        rootMenuPath.value = rootMenu?.path ?? '';
        splitSideMenus.value = rootMenu?.children ?? [];
    }

    watch(
        () => route.path,
        (path) => {
            const currentPath = (route?.meta?.activePath as string) ?? path;
            calcSideMenus(currentPath);
            if (rootMenuPath.value)
                defaultSubMap.set(rootMenuPath.value, currentPath);
        },
        {immediate: true},
    );

    // 初始化计算侧边菜单
    onBeforeMount(() => {
        calcSideMenus(route.meta?.activePath || route.path);
    });

    return {
        handleMenuSelect,
        handleMenuOpen,
        headerActive,
        headerMenus,
        sidebarActive,
        sidebarMenus,
        sidebarVisible,
    };
}

export {useMixedMenu};
